package com.tianji.remark.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tianji.api.dto.remark.LikedTimesDTO;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.domain.R;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.ObjectUtils;
import com.tianji.common.utils.StringUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.remark.domain.dto.LikeRecordFormDTO;
import com.tianji.remark.domain.po.LikedRecord;
import com.tianji.remark.mapper.LikedRecordMapper;
import com.tianji.remark.service.ILikedRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.messaging.simp.user.UserRegistryMessageHandler;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.tianji.common.constants.MqConstants.Exchange.LIKE_RECORD_EXCHANGE;
import static com.tianji.common.constants.MqConstants.Key.LIKED_TIMES_KEY_TEMPLATE;
import static com.tianji.remark.constants.RedisConstants.LIKE_BIZ_KEY_PREFIX;

/**
 * <p>
 * 点赞记录表 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-03-26
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LikedRecordServiceImpl extends ServiceImpl<LikedRecordMapper, LikedRecord> implements ILikedRecordService {

    private final LikedRecordMapper likedRecordMapper;
    private final RabbitMqHelper rabbitMqHelper;
    private final StringRedisTemplate redisTemplate;

    /**
     * 用于高亮显示用的，查询点赞状态记录
     * @param ids
     * @return
     */
    @Override
    public List<LikedTimesDTO> getByIds(List<Long> ids) {
        QueryWrapper<LikedRecord> queryWrapper = new QueryWrapper<>();
        // 学习课表微服务。用来统计本周学习小节数，指的是lessonId到本周学习小节数的一个map
        queryWrapper
                .select("biz_id, count(*) num")
                .in(ObjectUtils.isNotEmpty(ids), "biz_id", ids)
                .groupBy("biz_id")
                .having("num > 0");

        List<Map<String, Object>> maps = likedRecordMapper.selectMaps(queryWrapper);
        if (ObjectUtils.isNotEmpty(maps)) {
            List<LikedTimesDTO> likedTimesDTOList = maps.stream()
                    .map(map-> {
                        LikedTimesDTO dto = new LikedTimesDTO();
                        dto.setBizId(Long.parseLong(map.get("biz_id").toString()));
                        dto.setLikedTimes(Integer.parseInt(map.get("num").toString()));
                        return dto;
                    })
                    .collect(Collectors.toList());
            return likedTimesDTOList;
        } else {
            return new ArrayList<>();
        }
    }

    @Override
    public void addLike(LikeRecordFormDTO likeRecordFormDTO) {
        // 可以
        LikedTimesDTO likedTimesDTO = null;
        if (likeRecordFormDTO.getLiked()) {
            likedTimesDTO = liked(likeRecordFormDTO);
        } else {
            likedTimesDTO = cancelLiked(likeRecordFormDTO);
        }

        if (ObjectUtils.isNotEmpty(likedTimesDTO)) {
            rabbitMqHelper.sendAsyn(LIKE_RECORD_EXCHANGE,  "reply", likedTimesDTO);
        }

    }

    private LikedTimesDTO liked(LikeRecordFormDTO likeRecordFormDTO) {
        LikedRecord likedRecord1 = BeanUtils.copyBean(likeRecordFormDTO, LikedRecord.class);
        Long bizId = likeRecordFormDTO.getBizId();
        // 读数据库
        LikedRecord one = this.lambdaQuery().eq(LikedRecord::getUserId, UserContext.getUser())
                .eq(LikedRecord::getBizId, likeRecordFormDTO.getBizId())
                .one();
        // 查询点赞和取消点赞
        if (ObjectUtils.isNotEmpty(one) && !likeRecordFormDTO.getLiked()) {
            // 已经点过赞了，直接返回
            return null;
        }
        // 写数据库
        this.save(likedRecord1);
        
        // 一点也不好，高并发写的情况下压力非常大
        // 第二次读
        Integer count = this.lambdaQuery()
                .eq(LikedRecord::getBizId, bizId)
                .count();

        // 一共两次读，两次写，最后一次写发生在远程微服务
        return LikedTimesDTO.of(bizId, count);
    }

    private LikedTimesDTO cancelLiked(LikeRecordFormDTO likeRecordFormDTO) {

        // 走取消点赞逻辑
        LikedTimesDTO likeDTO = LikedTimesDTO.of(likeRecordFormDTO.getBizId(), -1);
        this.lambdaUpdate()
                .eq(LikedRecord::getBizId, likeRecordFormDTO.getBizId())
                .eq(LikedRecord::getUserId, UserContext.getUser())
                .remove();
        return likeDTO;
    }

    @Override
    public Map<Long, Boolean> isLiked(List<Long> ids) {
        // biz_id, true/false
        List<LikedRecord> list = this.lambdaQuery()
                .eq(LikedRecord::getUserId, UserContext.getUser())
                .list();
        Map<Long, Boolean> mp = list.stream().collect(Collectors.toMap(v -> v.getBizId(), v -> true));

        return mp;
    }

    @Override
    public void readLikeTimesAndSendMessage() {
        
    }
}
